package com.sky.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.StatusConstant;
import com.sky.dto.DishDTO;
import com.sky.dto.DishPageQueryDTO;
import com.sky.entity.Dish;
import com.sky.entity.DishFlavor;
import com.sky.entity.SetmealDish;
import com.sky.exception.BaseException;
import com.sky.exception.DeletionNotAllowedException;
import com.sky.mapper.DishFlavorMapper;
import com.sky.mapper.DishMapper;
import com.sky.mapper.SetmealDishMapper;
import com.sky.result.PageResult;
import com.sky.service.DishService;
import com.sky.utils.ParaVerifUtil;
import com.sky.vo.DishVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

@Service
@Slf4j
public class DishServicelmpl implements DishService {

    @Autowired
    private DishMapper dishMapper;

    @Autowired
    private DishFlavorMapper dishFlavorMapper;

    @Autowired
    private SetmealDishMapper setmealDishMapper;

    @Override
    //事物注解，用于事务控制
    @Transactional
    public boolean saveWithFlavour(DishDTO dishDTO) {
        log.info("saveWithFlavour: {}", dishDTO);
        //插入菜品表数据
        Dish dish = new Dish();
        BeanUtils.copyProperties(dishDTO, dish);
        //返回插入的行数主键值
        dishMapper.insert(dish);

        //插入菜品口味表数据
        List<DishFlavor> flavors = dishDTO.getFlavors();
        if (ParaVerifUtil.isEmpty(flavors))return false;
        for (DishFlavor flavor : flavors) {
            flavor.setDishId(dish.getId());
        }
        int rows = dishFlavorMapper.insertBatch(flavors);

        return rows>0;
    }

    @Override
    public PageResult list(DishPageQueryDTO dishPageQueryDTO) {

        try {
            //分页查询
            Dish dish = new Dish();
            BeanUtils.copyProperties(dishPageQueryDTO, dish);
            //开始分页
            PageHelper.startPage(dishPageQueryDTO.getPage(), dishPageQueryDTO.getPageSize());
            Page<DishVO> page = dishMapper.list(dish);
            return new PageResult(page.getTotal(), page.getResult());

        }catch (Exception e){
            log.error("list error: {}", e.getMessage());
            throw new BaseException("查询失败");
        }

    }

    @Override
    @Transactional
    public boolean delete(List<Long> ids) {
        //判断是否可以删除
        for (Long id : ids){
            //不可以删除则抛出异常
            verifyDelete(id);
        }

        try {
            //删除菜品口味表数据
            dishFlavorMapper.deleteByDishIds(ids);
            //删除菜品表数据
            dishMapper.deleteBatch(ids);
            return true;
        }catch (Exception e){
            log.error("delete error: {}", e.getMessage());
            throw new DeletionNotAllowedException("删除失败");
        }

    }

    @Override
    public void sale(List<Long> ids, Boolean saleStatus) {
        if (saleStatus){
            dishMapper.updateSaleStatus(ids, StatusConstant.ENABLE);
        } else {
            dishMapper.updateSaleStatus(ids, StatusConstant.DISABLE);
        }
    }



    @Override
    @Transactional
    public void update(DishDTO dishDTO) {
        try {

            //删除原有的菜品口味表数据
            dishFlavorMapper.deleteByDishId(dishDTO.getId());
            //插入新的菜品口味表数据
            dishFlavorMapper.insertBatch(dishDTO.getFlavors());
            //更新菜品表基础数据
            Dish dish = new Dish();
            BeanUtils.copyProperties(dishDTO, dish);
            dishMapper.update(dish);
        }catch (Exception e){
            throw new BaseException("修改菜品信息失败");
        }
    }

    @Override
    public DishVO getById(Long id) {
        Dish dish = dishMapper.selectById(id);
        List<DishFlavor> flavors = dishFlavorMapper.selectByDishId(id);
        //复制dish成VO对象（后端传给前端的VO对象，只包含必要的字段）
        DishVO dishVO = new DishVO();
        BeanUtils.copyProperties(dish, dishVO);
        dishVO.setFlavors(flavors);
        return dishVO;

    }




    @Override
    public void updateStatus(Long dishId, int status) {
        dishMapper.updateStatus(dishId, status);
    }

    @Override
    public List<DishVO> listByCategoryId(Long categoryId) {
       try {
           List<DishVO> dishList =dishMapper.listCategoryId(categoryId);
           return dishList;

       }catch (Exception e){
           log.error("listByCategoryId error: {}", e.getMessage());
           throw new BaseException("查询失败");
       }


    }




    /*
    * 判断是否可以删除
    1.判断菜品是否在起售状态
    2.判断菜品是否被套餐表关联
    * 如果不可以删除，则抛出DeletionNotAllowedException异常
    * */
    private void verifyDelete(Long id) {
        Dish dish = dishMapper.selectById(id);
        Integer status = dish.getStatus();
        String name = dish.getName();
        //判断菜品是否在起售状态
        if (Objects.equals(status, StatusConstant.ENABLE)){
            log.error("菜品{}在起售状态，不允许删除", id);
            throw new DeletionNotAllowedException("菜品["+name+"]在起售状态，不允许删除");
        }

        List<SetmealDish> setmealDishes = setmealDishMapper.selectByDishId(id);
        //判断菜品是否被套餐表关联
        if (!ParaVerifUtil.isEmpty(setmealDishes)){
            log.error("菜品{}已被套餐表关联，不允许删除", id);
            //有关联，不允许删除
            throw new DeletionNotAllowedException("菜品["+name+"]已被"+setmealDishes.size()+"个套餐表关联，不允许删除");
        }

    }



    //用户端接口
    //根据dish中的分类id查询菜品列表，并返回每个菜品的口味列表
    @Override
    public List<DishVO> listWithFlavor(Dish dish) {
        try{
            //查询菜品列表
            List<DishVO>  dishList = dishMapper.list(dish);
            //设置每个菜品的口味列表
            if (!ParaVerifUtil.isEmpty(dishList)){
                for (DishVO dishVO : dishList){
                    List<DishFlavor> flavors = dishFlavorMapper.selectByDishId(dishVO.getId());
                    dishVO.setFlavors(flavors);
                }
            }
            return dishList;
        }catch (Exception e){
            log.error("listWithFlavor error: {}", e.getMessage());
            throw new BaseException("查询分类失败");
        }


    }



}
